#include<iostream>
using namespace std;

class copyConstruct {
    public:
        int* data;
        // 默认的构造函数
        copyConstruct()
        {
            data = new int[10];
            cout<<"默认构造函数"<<endl;
        }
        // 拷贝构造函数
        copyConstruct(const copyConstruct& other)
        {
            data = new int[10];
            std::copy(other.data, other.data + 10, data);
            cout<<"拷贝构造函数"<<endl;
        }
        // 拷贝赋值运算符
        copyConstruct& operator=(const copyConstruct& other)
        {
            if (this != &other) {
                delete[] data;
                data = new int[10];
                std::copy(other.data, other.data + 10, data);
            }
            cout<<"拷贝赋值运算符"<<endl;
            return *this;
        }
        // 移动构造函数
        copyConstruct(copyConstruct&& other) noexcept
        {
            // 移动构造函数的大致步骤:
            // 1. 资源所有权的转移
            // 2. 源所有者变成 有效但是未定义的状态
            data = other.data;
            other.data = nullptr; // 函数入参不能是常量引用，因为要修改入参中的成员变量
            cout<<"移动构造函数"<<endl;
        }

        //移动赋值运算符
        copyConstruct& operator=(copyConstruct&& other) noexcept
        {
            /*
                移动赋值运算符的大致步骤:
                1、先处理自赋值的场景
                2、目标对象释放所持有的资源
                3、源对象的资源持有权转移给目标对象
                4、源对象切换为有效但是未定义的状态
            */
           if (this != &other) {
                delete[] data;
                data = other.data;
                other.data = nullptr;
           }
           cout<<"移动赋值运算符"<<endl;
           return *this;
        }
        ~copyConstruct()
        {
            delete[] data;
            cout<<"析构函数"<<endl;
        }
};

copyConstruct getCopy()
{
    return copyConstruct();
}

copyConstruct getCopyNext()
{
    copyConstruct cc;
    return cc;
}
int main()
{
    // 默认构造函数
    copyConstruct a;
    copyConstruct b;
    copyConstruct c = a; // 拷贝构造函数
    b = c; // 拷贝赋值运算符
    cout<<"================================================"<<endl;
    cout<<"***d begin***"<<endl;
    copyConstruct d = getCopy(); // 移动构造函数
    cout<<"***d end***"<<endl;

    cout<<"***e begin***"<<endl;
    copyConstruct e = getCopyNext(); // 移动构造函数
    cout<<"***e end***"<<endl;

    cout<<"***f begin***"<<endl;
    copyConstruct f = std::move(e); // 移动构造函数
    cout<<"***f end***"<<endl;

    cout<<"***g begin    1***"<<endl;
    copyConstruct g;
    g = std::move(f); // 移动赋值运算符
    cout<<"***g end***"<<endl;
    

    cout<<"***g begin    2***"<<endl;
    g = getCopyNext(); // 移动赋值运算符
    cout<<"***g end***"<<endl;


    cout<<"***g begin    3***"<<endl;
    g = getCopy(); // 移动赋值运算符
    cout<<"***g end***"<<endl;
    return 0;
}